package com.grape.handler;

import com.alibaba.fastjson.JSON;
import com.grape.model.UserContext;
import com.grape.result.ImServerResult;
import com.grape.session.ISessionStore;
import com.grape.session.IUserChannelStore;
import com.grape.session.impl.UserChannelStoreImpl;
import com.grape.utils.SpringUtil;
import com.grape.utils.StringUtils;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import org.slf4j.Logger;

import java.util.concurrent.ConcurrentHashMap;

import static io.lettuce.core.pubsub.PubSubOutput.Type.message;

@ChannelHandler.Sharable
public class MessageHandler extends SimpleChannelInboundHandler<Object> {
    
    private static final Logger logger = org.slf4j.LoggerFactory.getLogger(MessageHandler.class);

    private static final ConcurrentHashMap<Channel, String> ONLINE_WS_MAP = new ConcurrentHashMap<>();

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        logger.info("收到消息：{}", ((TextWebSocketFrame) msg).text());
        try {
            ImServerResult imServerResult = JSON.parseObject(((TextWebSocketFrame) msg).text(), ImServerResult.class);
            if (ImServerResult.SIGN_HEARTBEAT_DETECTION.equals(imServerResult.getKey())) {
                IUserChannelStore userChannelStore = SpringUtil.getBean(IUserChannelStore.class);
                // TODO
//                String userId = SpringUtil.getBean(JwtUtil.class).getUserId(imServerResult.getToken());
//                userChannelStore.updateLastResetTimeByUserId(imServerResult.getData(), userId);
                return;
            }

            logger.error("未知的消息类型，消息内容为：{}", message);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("处理消息异常： " + e.getMessage());
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        ISessionStore sessionStore = SpringUtil.getBean(ISessionStore.class);
        sessionStore.removeChannel(ctx.channel());
        logger.info("客户端断开连接：{}", ctx.channel());
        String userId = ctx.channel().attr(UserChannelStoreImpl.USER_ID_ATTRIBUTE_KEY).get();
        if (StringUtils.isBlank(userId)) {
            return;
        }
        logger.info("用户id：{}断开连接", userId);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        IUserChannelStore userChannelStore = SpringUtil.getBean(IUserChannelStore.class);
        if (evt instanceof UserContext) {
            logger.info("用户校验通过");
        } else if (evt instanceof WebSocketServerProtocolHandler.HandshakeComplete) {
            logger.info("完成握手");
            ISessionStore sessionStore = SpringUtil.getBean(ISessionStore.class);
            sessionStore.addChannel(ctx.channel());
            logger.info("客户端加入连接：{}", ctx.channel());
            UserContext userContext = ctx.channel()
                    .attr(UserAuthHandler.USER_CONTEXT_ATTRIBUTE_KEY).get();
            userChannelStore.bindUserToChannel(userContext.getUserId(), ctx.channel(), userContext.getToken());
            ONLINE_WS_MAP.putIfAbsent(ctx.channel(), userContext.getUserId());
        }
        super.userEventTriggered(ctx, evt);
    }
}
